<?php

namespace EasyVote\EasyVoteBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * User
 * Stores a user in the database.
 * @ORM\Entity(repositoryClass="EasyVote\EasyVoteBundle\Repository\UserRepository")
 */
class User implements UserInterface
{
    /**
     * The id of the user
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * The profile of the user
     * @var Profile
     * @ORM\ManyToOne(targetEntity="Profile")
     */
    private $profile;

    /**
     * Gets the profile of the user
     * @return Profile
     */
    public function getProfile()
    {
        return $this->profile;
    }

    /**
     * Sets the profile of the user
     * @param Profile $profile
     */
    public function setProfile($profile)
    {
        $this->profile = $profile;
    }

    /**
     * The University-issued EUID of the user, such as xyz1234
     * @var string
     *
     * @ORM\Column(name="euid", type="string")
     */
    private $euid;

    /**
     * How the user wants his/her name displayed.
     * @var string
     *
     * @ORM\Column(name="displayName", type="string", nullable=true)
     */
    private $displayName;

    /**
     * The email addresses of the user.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Email")
     * @ORM\JoinTable(name="users_emails",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="email_id", referencedColumnName="id")}
     *      )
     */
    private $emails;

    /**
     * The user's gender (male or female)
     * @var Gender
     * @ORM\ManyToOne(targetEntity="Gender")
     */
    private $gender;

    /**
     * The user's scoped affiliations (e.g. student@unt.edu)
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="ScopedAffiliation")
     * @ORM\JoinTable(name="users_scopedaffiliations",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="scopedaffiliation_id", referencedColumnName="id")}
     *      )
     */
    private $scopedAffiliations;

    /**
     * The person's principal name (xyz1234@unt.edu)
     * @var string
     * @ORM\Column(name="principalName", type="string")
     */
    private $principalName;

    /**
     * The user's university ID number, such as 10823456
     * @var string
     * @ORM\Column(name="employeeNumber", type="string")
     */
    private $employeeNumber;

    /**
     * The unscoped affiliations, such as 'student', 'member', 'faculty', or 'staff'
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Affiliation")
     * @ORM\JoinTable(name="users_affiliations",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="affiliation_id", referencedColumnName="id")}
     *      )
     */
    private $affiliations;

    /**
     * The users' degrees.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Degree")
     * @ORM\JoinTable(name="users_degrees",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="degree_id", referencedColumnName="id")}
     *      )
     */
    private $degrees;

    /**
     * The user's classification (freshman, sophomore, junior, senior, grad student, faculty)
     * @var Classification
     * @ORM\ManyToOne(targetEntity="Classification")
     */
    private $classification;

    /**
     * Stores the user's jobs
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Job")
     * @ORM\JoinTable(name="users_jobs",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="job_id", referencedColumnName="id")}
     *      )
     */
    private $jobs;

    /**
     * Stores the user's roles.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Role")
     * @ORM\JoinTable(name="users_roles",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
     *      )
     */
    private $roleObjects;

    /**
     * Default constructor.
     */
    public function __construct()
    {
        $this->roleObjects = new ArrayCollection;
        $this->jobs = new ArrayCollection;
        $this->affiliations = new ArrayCollection;
        $this->degrees = new ArrayCollection;
        $this->scopedAffiliations = new ArrayCollection;
        $this->emails = new ArrayCollection;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {

        return $this->id;
    }

    /**
     * Gets the password. Required to override but does nothing as we are not storing passwords.
     * @return null
     */
    public function getPassword()
    {
        return null;
    }

    /**
     * Gets the salt. Required to override but does nothing as we are not storing passwords.
     * @return null
     */
    public function getSalt()
    {
        return null;
    }

    /**
     * Gets the username. For this application it is the EUID.
     * @return string the EUID.
     */
    public function getUsername()
    {
        return $this->euid;
    }

    /**
     * Set euid
     *
     * @param string $euid
     * @return User
     */
    public function setEuid($euid)
    {
        $this->euid = $euid;

        return $this;
    }

    /**
     * Get euid
     *
     * @return string
     */
    public function getEuid()
    {
        return $this->euid;
    }

    /**
     * Set gender
     * @param Gender $gender
     */
    public function setGender(Gender $gender)
    {
        $this->gender = $gender;
    }

    /**
     * Get gender
     * @return string
     */
    public function getGender()
    {
        return $this->gender;
    }

    /**
     * Set employee number
     *
     * @param string $employeeNumber
     * @return User
     */
    public function setEmployeeNumber($employeeNumber)
    {
        $this->employeeNumber = $employeeNumber;

        return $this;
    }

    /**
     * Get employee number
     *
     * @return string
     */
    public function getEmployeeNumber()
    {
        return $this->employeeNumber;
    }

    /**
     * Set the name to be displayed
     *
     * @param string $displayName
     * @return User
     */
    public function setDisplayName($displayName)
    {
        $this->displayName = $displayName;

        return $this;
    }

    /**
     * Get display name
     *
     * @return string
     */
    public function getDisplayName()
    {
        return $this->displayName;
    }

    /**
     * Set principal name (often euid@unt.edu)
     *
     * @param string $principalName
     * @return User
     */
    public function setPrincipalName($principalName)
    {
        $this->principalName = $principalName;
        return $this;
    }

    /**
     * Get principal name
     *
     * @return string
     */
    public function getPrincipalName()
    {
        return $this->principalName;
    }

    /**
     * Add an email
     * @param Email $email
     */
    public function addEmail(Email $email)
    {
        if (!$this->emails->contains($email)) {
            $this->emails[] = $email;
        }
    }

    /**
     * Get emails
     *
     * @return ArrayCollection
     */
    public function getEmails()
    {
        return $this->emails;
    }

    /**
     * Remove email
     *
     * @param email $email
     */
    public function removeEmail(Email $email)
    {
        $this->emails->removeElement($email);
    }

    /**
     * Get scoped affiliations
     *
     * @return ArrayCollection
     */
    public function getScopedAffiliations()
    {
        return $this->scopedAffiliations;
    }

    /**
     * Add Scoped affiliation
     *
     * @param ScopedAffiliation $scopedAffiliation
     * @return User
     */
    public function addScopedAffiliation(ScopedAffiliation $scopedAffiliation)
    {
        if ($this->scopedAffiliations->contains($scopedAffiliation)) {

        } else {
            $this->scopedAffiliations[] = $scopedAffiliation;
        }
        return $this;
    }

    /**
     * Remove scoped affiliation
     *
     * @param ScopedAffiliation $scopedAffiliation
     */
    public function removeScopedAffiliation(ScopedAffiliation $scopedAffiliation)
    {
        $this->scopedAffiliations->removeElement($scopedAffiliation);
    }

    /**
     * Get affiliations
     *
     * @return ArrayCollection
     */
    public function getAffiliations()
    {
        return $this->affiliations;
    }

    /**
     * Add affiliation
     *
     * @param Affiliation $affiliation
     * @return User
     */
    public function addAffiliation(Affiliation $affiliation)
    {
        if ($this->affiliations->contains($affiliation)) {

        } else {
            $this->affiliations[] = $affiliation;
        }
        return $this;
    }

    /**
     * Remove affiliation
     *
     * @param Affiliation $affiliation
     */
    public function removeAffiliation(Affiliation $affiliation)
    {
        $this->affiliations->removeElement($affiliation);
    }

    /**
     * Get degrees
     *
     * @return ArrayCollection
     */
    public function getDegrees()
    {
        return $this->degrees;
    }

    /**
     * Add degree
     *
     * @param Degree $degree
     * @return User
     */
    public function addDegree(Degree $degree)
    {
        if ($this->degrees->contains($degree)) {

        } else {
            $this->degrees[] = $degree;
        }
        return $this;
    }

    /**
     * Remove degree
     *
     * @param Degree $degree
     */
    public function removeDegree(Degree $degree)
    {
        $this->degrees->removeElement($degree);
    }

    /**
     * Set classification
     *
     * @param Classification $classification
     * @return User
     */
    public function setClassification($classification)
    {
        $this->classification = $classification;

        return $this;
    }

    /**
     * Get classification
     *
     * @return Classification
     */
    public function getClassification()
    {
        return $this->classification;
    }

    /**
     * Get jobs
     *
     * @return ArrayCollection
     */
    public function getJobs()
    {
        return $this->jobs;
    }

    /**
     * Add job
     *
     * @param Job $job
     * @return User
     */
    public function addJob(Job $job)
    {
        if ($this->jobs->contains($job)) {

        } else {
            $this->jobs[] = $job;
        }
        return $this;
    }

    /**
     * Remove job
     *
     * @param Job $job
     */
    public function removeJob(Job $job)
    {
        $this->jobs->removeElement($job);
    }

    /**
     * Add roles
     *
     * @param Role $role
     * @return User
     */
    public function addRole(Role $role)
    {
        if ($this->roleObjects->contains($role)) {

        } else {
            $this->roleObjects[] = $role;
        }
        return $this;
    }

    /**
     * Remove role
     *
     * @param Role $role
     */
    public function removeRole(Role $role)
    {
        $this->roleObjects->removeElement($role);
    }

    /**
     * Get roles
     *
     * @return ArrayCollection
     */
    public function getRoleObjects()
    {
        return $this->roleObjects;
    }

    /**
     * Gets the roles that the user is a part of
     * @return array
     */
    public function getRoles()
    {
        return $this->roleObjects->toArray();
    }

    /**
     * Determines if the user is an admin
     * @return true if the user is an admin; otherwise false.
     */
    public function isAdmin(){
        foreach($this->roleObjects as $role){
            if($role->getValue() == 'ROLE_ADMIN'){
                return true;
            }
        }
        return false;
    }

    /**
     * This was a required override.
     */
    public function eraseCredentials()
    {

    }
}